home *** CD-ROM | disk | FTP | other *** search
/ Ultimedia 1 / Ultimedia 1.iso / tools / grafiktools / showpicasso / source / sp_iff.c < prev    next >
Encoding:
Text File  |  1994-06-26  |  10.3 KB  |  553 lines

  1. /* Routinen für IFF ILBM-Dateien
  2. ** File: spiff.c
  3. */
  4.  
  5.  
  6. /* Unterroutine zum Test auf FORM ILBM, RGBN und RGB8 */
  7.  
  8.  
  9. BYTE IsIFF(struct IFFHandle *iff)
  10. {
  11.  LONG              error = NULL;
  12.  struct ContextNode *top = NULL;
  13.  
  14.  if(!(error=ParseIFF(iff,IFFPARSE_RAWSTEP)))
  15.  {
  16.  
  17.   if(top=CurrentChunk(iff))
  18.   {
  19.  
  20.    if((top->cn_Type) == ID_ILBM) return(1L);
  21.    if((top->cn_Type) == MAKE_ID('R','G','B','N')) return(2L);
  22.    if((top->cn_Type) == MAKE_ID('R','G','B','8')) return(3L);
  23.   }
  24.  }
  25.  else 
  26.  {
  27.   if(error != -10L) OutText(localstr[MSG_EPARSEIFF]);
  28.  }
  29.  
  30.  return(NULL);
  31. }
  32.  
  33.  
  34. /* Einlesen des BMHD Chunk in die Struktur */
  35.  
  36.  
  37. BOOL GetBMHD(struct IFFHandle *iff,BitMapHeader *bmap)
  38. {
  39.  if(ReadChunkBytes(iff,bmap,20L) == 20L) return(TRUE);
  40.  return(FALSE);
  41. }
  42.  
  43.  
  44. /* Einlesen des CAMG Chunk */
  45.  
  46.  
  47. BOOL GetCAMG(struct IFFHandle *iff,ULONG *mode)
  48. {
  49.  if(ReadChunkBytes(iff,mode,4L) == 4L) return(TRUE);
  50.  return(FALSE);
  51. }
  52.  
  53.  
  54. /* Einlesen des CMAP Chunk in ColorRegister */
  55.  
  56.  
  57. BOOL GetCMAP(struct IFFHandle *iff,UBYTE *creg,LONG cnum)
  58.  if(ReadChunkBytes(iff,creg,3*cnum) == 3*cnum) return(TRUE);
  59.  return(FALSE);
  60. }
  61.  
  62.  
  63. /* Einlesen des BODY Chunk aus einer IFF ILBM Datei */
  64.  
  65.  
  66. LONG GetBODY_ILBM(struct IFFHandle *iff,BitMapHeader *bmap,ULONG mode,struct Screen *scr)
  67. {
  68.  UWORD        width = scr->Width; /* screen width */
  69.  UWORD      height = scr->Height; /* screen height */
  70.  
  71.  LONG                  ok = TRUE;
  72.  LONG              actual = NULL;
  73.  LONG                     bcount;
  74.  UWORD                    bpline; /* Anzahl der Bytes in einer Zeile */
  75.  LONG           pixoffset = NULL;
  76.  UWORD                    wpline; /* Anzahl der Words in einer Zeile */
  77.  WORD             gfxmode = NULL;
  78.  register WORD       min128=-128;
  79.  register LONG srcbytes,dstbytes;
  80.  register BYTE           *source;
  81.  register BYTE             *dest;
  82.  register BYTE          *scrbase;
  83.  register UWORD     *sbuf = NULL; /* Buffer für eine Bildzeile */
  84.  register UBYTE   *hambuf = NULL; /* Buffer für eine HAM Bildzeile */
  85.  register WORD           c,h,p,n;
  86.  
  87.  gfxmode = 8;
  88.  
  89.  if(mode & HAM_KEY)
  90.  {
  91.   if(bmap->nPlanes == 6) gfxmode = 12;
  92.   if(bmap->nPlanes == 8) gfxmode = 23;
  93.  }
  94.  
  95.  if(USERFLGS & PFLG_TRUECLR)              
  96.  {
  97.   gfxmode = 24;
  98.   if(USERFLGS & PFLG_TC15BIT) gfxmode = 15;
  99.   if(USERFLGS & PFLG_TC16BIT) gfxmode = 16;
  100.  }
  101.  
  102.  bpline = (ULONG)(bmap->w / 8);
  103.  if(((LONG)bmap->w) % 8) bpline++;
  104.  if(((LONG)bpline) % 2) bpline++;
  105.  
  106.  bcount = (bmap->nPlanes) * bpline;
  107.  wpline = bpline / 2;
  108.  
  109.  scrbase = LockVillageScreen(scr);
  110.  
  111.  if(!(USERFLGS & UFLG_NOCENTER)) /* Zentrierung des Bildes auf dem Screen */
  112.  {
  113.   switch(gfxmode)
  114.   {
  115.    case 8:
  116.  
  117.    scrbase += (((height) - (bmap->h)) / 2 * (width)) + (((width) - (bmap->w)) / 2);
  118.    break;
  119.  
  120.    case 12:
  121.    case 15:
  122.    case 16:
  123.  
  124.    scrbase += (((height) - (bmap->h)) / 2 * (width) * 2) + (((width) - (bmap->w)) / 2 * 2);
  125.    break;
  126.  
  127.    case 23:
  128.    case 24:
  129.  
  130.    scrbase += (((height) - (bmap->h)) / 2 * (width) * 3) + (((width) - (bmap->w)) / 2 * 3);
  131.    break;
  132.   }
  133.  }
  134.  
  135.  if(sbuf = AllocVec((ULONG)(bpline*(UWORD)bmap->nPlanes),MEMF_PUBLIC|MEMF_CLEAR))
  136.  {
  137.  
  138.   if(mode & HAM_KEY) 
  139.   {
  140.    if(!(hambuf = AllocVec((ULONG)bmap->w,MEMF_PUBLIC|MEMF_CLEAR)))
  141.    {
  142.     ok = FALSE;
  143.     goto ByteError;
  144.    }
  145.   }
  146.  
  147.   if(bmap->compression)
  148.   {
  149.    srcbytes = ReadChunkBytes(iff,cbuf,cbufsize); /* Lesen der Daten nach cbuf */
  150.    source = cbuf;
  151.   }
  152.  
  153.   for(h=0; h < (bmap->h); h++)
  154.   {
  155.  
  156.    if(bmap->compression) 
  157.    {
  158.     dest = (BYTE *)sbuf;
  159.  
  160.     for(p=0; p < (bmap->nPlanes); p++)
  161.     {
  162.      dstbytes = bpline;
  163.  
  164.      while(dstbytes > 0)
  165.      {
  166.  
  167.       if((srcbytes -= 1) < 0)
  168.       {
  169.  
  170.        if((srcbytes = ReadChunkBytes(iff,cbuf,cbufsize) - 1) < 0)
  171.        {
  172.         ok = FALSE;
  173.         goto ByteError;
  174.        }
  175.        source = cbuf;
  176.       }
  177.  
  178.       n = *source++;
  179.      
  180.       if(n >= 0)
  181.       {
  182.        n += 1;
  183.  
  184.        if((srcbytes -= n) < 0) 
  185.        {
  186.         srcbytes += n;
  187.  
  188.         for(c=0; c < srcbytes; c++) cbuf[c] = *source++;
  189.  
  190.         if(ReadChunkBytes(iff,&cbuf[srcbytes],cbufsize - srcbytes) < 0) 
  191.         {
  192.          ok = FALSE;
  193.          goto ByteError;
  194.         }
  195.         srcbytes = cbufsize-n;
  196.         source = cbuf;
  197.        }
  198.  
  199.        if((dstbytes -= n) < 0) break;
  200.        do (*dest++ = *source++); while(--n > 0);
  201.       }
  202.  
  203.       else if(n != min128)
  204.       {
  205.        n = -n + 1;
  206.  
  207.        if((srcbytes -= 1) < 0)
  208.        {
  209.  
  210.         if((srcbytes = ReadChunkBytes(iff,cbuf,cbufsize) - 1) < 0)
  211.         {
  212.          ok = FALSE;
  213.          goto ByteError;
  214.         }
  215.         source = cbuf;
  216.        }
  217.  
  218.        if((dstbytes -= n) < 0) break;
  219.        c = *source++;
  220.        do *dest++ = c; while(--n > 0);
  221.       }
  222.      }
  223.     }
  224.    }
  225.    else actual = ReadChunkBytes(iff,sbuf,bcount);
  226.  
  227.    switch(gfxmode)
  228.    {
  229.     case 8:
  230.  
  231.     Convert8(&scrbase[pixoffset],sbuf,bmap->nPlanes,bpline);
  232.     pixoffset += width;
  233.     break;
  234.  
  235.     case 12:
  236.  
  237.     ConvertHAM6(&scrbase[pixoffset],sbuf,hambuf,color,bpline);
  238.     pixoffset += width*2;
  239.     break;
  240.  
  241.  
  242.     case 15:
  243.  
  244.     Convert15(&scrbase[pixoffset],sbuf,bpline);
  245.     pixoffset += width*2;
  246.     break;
  247.  
  248.     case 16:
  249.  
  250.     Convert16(&scrbase[pixoffset],sbuf,bpline);
  251.     pixoffset += width*2;
  252.     break;
  253.  
  254.     case 23:
  255.  
  256.     ConvertHAM8(&scrbase[pixoffset],sbuf,hambuf,color,bpline);
  257.     pixoffset += width*3;
  258.     break;
  259.     
  260.     case 24:
  261.  
  262.     Convert24(&scrbase[pixoffset],sbuf,bpline);
  263.     pixoffset += width*3;
  264.     break;
  265.  
  266.    }
  267.   }
  268.  
  269. ByteError:
  270.  
  271.   if(hambuf) FreeVec(hambuf);
  272.   FreeVec(sbuf);
  273.  }
  274.  
  275.  UnLockVillageScreen(scr); 
  276.  
  277.  return(ok);
  278. }
  279.  
  280.  
  281. /* Einlesen des BODY Chunk aus einer IFF RGBN bzw. RGB8 Datei */
  282.  
  283. LONG GetBODY_RGBx(struct IFFHandle *iff,BitMapHeader *bmap,struct Screen *scr)
  284. {
  285.  UWORD        width = scr->Width;
  286.  UWORD      height = scr->Height;
  287.  
  288.  LONG                  ok = TRUE;
  289.  LONG             pixoffset=NULL;
  290.  WORD               gfxmode=NULL;
  291.  register LONG srcbytes,dstbytes;
  292.  register UBYTE          *source;
  293.  register UBYTE            *dest;
  294.  register UBYTE         *scrbase;
  295.  register WORD               c,h;
  296.  
  297.  UBYTE            red,green,blue;
  298.  register UWORD    repeat = NULL;
  299.  
  300.  gfxmode = 12;
  301.  
  302.  if(USERFLGS & PFLG_TRUECLR)              
  303.  {
  304.   gfxmode = 24;
  305.   if(USERFLGS & PFLG_TC15BIT) gfxmode = 15;
  306.   if(USERFLGS & PFLG_TC16BIT) gfxmode = 16;
  307.  }
  308.  
  309.  scrbase = LockVillageScreen(s);
  310.  
  311.  if(!(USERFLGS & UFLG_NOCENTER)) 
  312.  {
  313.   switch(gfxmode)
  314.   {
  315.    case 12:
  316.    case 15:
  317.    case 16:
  318.  
  319.    scrbase += (((height) - (bmap->h)) / 2 * (width) * 2) + (((width) - (bmap->w)) / 2 * 2);
  320.    break;
  321.  
  322.    case 24:
  323.  
  324.    scrbase += (((height) - (bmap->h)) / 2 * (width) * 3) + (((width) - (bmap->w)) / 2 * 3);
  325.    break;
  326.   }
  327.  }
  328.  
  329.  srcbytes = ReadChunkBytes(iff,cbuf,cbufsize); /* Lesen der Daten nach cbuf */
  330.  source = cbuf;
  331.  
  332.  if(gfxmode != 12)
  333.  {
  334.  
  335.   for(h=0; h < (bmap->h); h++)
  336.   {
  337.    dest = &scrbase[pixoffset];
  338.  
  339.    dstbytes = bmap->w;
  340.  
  341.    while(dstbytes > 0)
  342.    {
  343.  
  344.     if(!repeat) /* 1) Wdh.zähler kann über eine Zeile hinaus reichen */
  345.     {
  346.  
  347.      if((srcbytes -= 4) < 0) 
  348.      {
  349.       srcbytes += 4;
  350.  
  351.       for(c=0; c < srcbytes; c++) cbuf[c] = *source++;
  352.  
  353.       if(ReadChunkBytes(iff,&cbuf[srcbytes],cbufsize - srcbytes) < 0) 
  354.       {
  355.        ok = FALSE;
  356.        goto RGBxError;
  357.       }
  358.       srcbytes = cbufsize-4;
  359.       source = cbuf;
  360.      }
  361.  
  362.      red    = *source++;
  363.      green  = *source++;
  364.      blue   = *source++;
  365.      repeat = (UWORD)(*source++ & 0x007f);
  366.  
  367.      if(!repeat)
  368.      {
  369.  
  370.       if((srcbytes -= 1) < 0)
  371.       {
  372.  
  373.        if(ReadChunkBytes(iff,cbuf,cbufsize) < 0)
  374.        {
  375.         ok = FALSE;
  376.         goto RGBxError;
  377.        }
  378.        srcbytes = cbufsize - 1;
  379.        source = cbuf;
  380.       }
  381.  
  382.       if(!(repeat = (UWORD)(*source++)))
  383.       {
  384.  
  385.        if((srcbytes -= 2) < 0) 
  386.        {
  387.         srcbytes += 2;
  388.  
  389.         for(c=0; c < srcbytes; c++) cbuf[c] = *source++;
  390.  
  391.         if(ReadChunkBytes(iff,&cbuf[srcbytes],cbufsize - srcbytes) < 0) 
  392.         {
  393.          ok = FALSE;
  394.          goto RGBxError;
  395.         }
  396.         srcbytes = cbufsize-2;
  397.         source = cbuf;
  398.        }
  399.  
  400.        repeat = (UWORD)((*source++)<<8);
  401.        repeat += (UWORD)*source++;
  402.       }
  403.      } 
  404.     }
  405.  
  406.     if((dstbytes -= repeat) < 0) repeat += dstbytes; /* siehe 1) */
  407.     
  408.     do
  409.     {
  410.      switch(gfxmode)
  411.      {
  412.       case 15:
  413.  
  414.       *dest++ = ((green<<2)&0xE0) | ((blue>>3)&0x1F);
  415.       *dest++ = ((green>>6)&0x03) | ((red>>1)&0x7C);
  416.       break;
  417.  
  418.       case 16:
  419.  
  420.       *dest++ = ((green<<3)&0xE0) | ((blue>>3)&0x1F);
  421.       *dest++ = ((green>>5)&0x07) | (red&0xF8);
  422.       break;
  423.  
  424.       case 24:
  425.  
  426.       *dest++ = blue;
  427.       *dest++ = green;
  428.       *dest++ = red; 
  429.       break;
  430.      }
  431.     } while(--repeat > 0);
  432.  
  433.     if(dstbytes < 0) /* siehe 1) */
  434.     {
  435.      repeat = -dstbytes;
  436.      break;
  437.     }
  438.  
  439.    }
  440.    switch(gfxmode)
  441.    {
  442.     case 15:
  443.     case 16:
  444.     pixoffset += width * 2;
  445.     break;
  446.  
  447.     case 24:
  448.     pixoffset += width * 3;
  449.     break;
  450.    }
  451.   }
  452.  }
  453.  else
  454.  {
  455.  
  456.   for(h=0; h < (bmap->h); h++)
  457.   {
  458.    dest = &scrbase[pixoffset];
  459.  
  460.    dstbytes = (LONG)bmap->w;
  461.  
  462.    while(dstbytes > 0)
  463.    {
  464.  
  465.     if(!repeat) /* 1) Wdh.zähler kann über eine Zeile hinaus reichen */
  466.     {
  467.  
  468.      if((srcbytes -= 2) < 0) 
  469.      {
  470.       srcbytes += 2;
  471.  
  472.       for(c=0; c < srcbytes; c++) cbuf[c] = *source++;
  473.  
  474.       if(ReadChunkBytes(iff,&cbuf[srcbytes],cbufsize - srcbytes) < 0) 
  475.       {
  476.        ok = FALSE;
  477.        goto RGBxError;
  478.       }
  479.       srcbytes = cbufsize - 2;
  480.       source = cbuf;
  481.      }
  482.  
  483.      red    = *source & 0xf0;
  484.      green  = (*source++<<4) & 0xf0;
  485.      blue   = *source & 0xf0;
  486.      repeat = (UWORD)(*source++ & 0x07);
  487.  
  488.      if(!repeat)
  489.      {
  490.  
  491.       if((srcbytes -= 1) < 0)
  492.       {
  493.  
  494.        if(ReadChunkBytes(iff,cbuf,cbufsize) < 0)
  495.        {
  496.         ok = FALSE;
  497.         goto RGBxError;
  498.        }
  499.        srcbytes = cbufsize - 1;
  500.        source = cbuf;
  501.       }
  502.  
  503.       if(!(repeat = (UWORD)(*source++)))
  504.       {
  505.  
  506.        if((srcbytes -= 2) < 0) 
  507.        {
  508.         srcbytes += 2;
  509.  
  510.         for(c=0; c < srcbytes; c++) cbuf[c] = *source++;
  511.  
  512.         if(ReadChunkBytes(iff,&cbuf[srcbytes],cbufsize - srcbytes) < 0) 
  513.         {
  514.          ok = FALSE;
  515.          goto RGBxError;
  516.         }
  517.         srcbytes = cbufsize - 2;
  518.         source = cbuf;
  519.        }
  520.  
  521.        repeat = (UWORD)((*source++)<<8);
  522.        repeat += (UWORD)*source++;
  523.       }
  524.      } 
  525.     }
  526.  
  527.     if((dstbytes -= repeat) < 0) repeat += dstbytes; /* siehe 1) */
  528.     
  529.     do
  530.     {
  531.      *dest++ = ((green<<2)&0xE0) | ((blue>>3)&0x1F);
  532.      *dest++ = ((green>>6)&0x03) | ((red>>1)&0x7C);
  533.     } while(--repeat > 0);
  534.  
  535.     if(dstbytes < 0) /* siehe 1) */
  536.     {
  537.      repeat = -dstbytes;
  538.      break;
  539.     }
  540.  
  541.    }
  542.    pixoffset += width * 2;
  543.   }
  544.  }
  545.  
  546. RGBxError:
  547.  
  548.  UnLockVillageScreen(s); 
  549.  
  550.  return(ok);
  551. }
  552.